package com.example.gobang.game;

import com.example.gobang.model.User;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.io.IOException;
import java.util.LinkedList;
import java.util.Queue;

/**
 * author: hyacinth
 * Date: 2023/5/25
 * 这个类负责 游戏的匹配功能
 */
@Component
public class Matcher {
    private ObjectMapper objectMapper = new ObjectMapper();

    private Queue<User> normalQueue = new LinkedList<>();
    private Queue<User> highQueue = new LinkedList<>();
    private Queue<User> veryHighQueue = new LinkedList<>();

    @Autowired
    private OnlineUserManager onlineUserManager;
    @Autowired
    private RoomManager roomManager;
    /**
     * 匹配中
     *
     * @param user
     */
    public void add(User user) {
        if (user.getScore() < 2000) {
            synchronized (normalQueue) {
                normalQueue.offer(user);
                normalQueue.notify();
            }
            System.out.println("把 用户 添加到了 normalQueue中");
        } else if (user.getScore() < 5000) {
            synchronized (highQueue) {
                highQueue.offer(user);
                highQueue.notify();
            }
            System.out.println("把 用户 添加到了 highQueue中");
        } else {
            synchronized (veryHighQueue) {
                veryHighQueue.offer(user);
                veryHighQueue.notify();
            }
            System.out.println("把 用户 添加到了 veryHighQueue中");
        }
    }

    /**
     * 停止匹配
     *
     * @param user
     */
    public void remove(User user) {
        if (user.getScore() < 2000) {
            synchronized (normalQueue) {
                normalQueue.remove(user);
            }
            System.out.println("把 用户 从 normalQueue 中删除");
        } else if (user.getScore() < 5000) {
            synchronized (highQueue) {
                highQueue.remove(user);
            }
            System.out.println("把 用户 从 highQueue中删除");
        } else {
            synchronized (veryHighQueue) {
                veryHighQueue.remove(user);
            }
            System.out.println("把 用户 从 veryHighQueue中删除");
        }
    }
    public Matcher() {
        Thread t1 = new Thread() {
            @Override
            public void run() {
                // 扫描 normalQueue
                while(true){
                    handlerMatch(normalQueue);
                }
            }
        };
        t1.start();
        Thread t2 = new Thread() {
            @Override
            public void run() {
                // 扫描 highQueue
                while (true){
                    handlerMatch(highQueue);
                }
            }
        };
        t2.start();
        Thread t3 = new Thread() {
            @Override
            public void run() {
                // 扫描 veryHighQueue
               while (true){
                   handlerMatch(veryHighQueue);
               }
            }
        };
        t3.start();
    }

    public void handlerMatch(Queue<User> matchQueue) {
        synchronized (matchQueue) {
            try {
                while (matchQueue.size() < 2) {
                    matchQueue.wait();
                }
                User player1 = matchQueue.poll();
                User player2 = matchQueue.poll();
                System.out.println("匹配出两个玩家: player1: " + player1.getUsername() + " player2: " + player2.getUsername());

                // 获取websocket会话
                WebSocketSession session1 = onlineUserManager.getSessionFromGameHall(player1.getUserId());
                WebSocketSession session2 = onlineUserManager.getSessionFromGameHall(player2.getUserId());
                // 理论上不会存在null的情况,双重判定
                if (session1 == null) {
                    matchQueue.offer(player2);
                    return;
                }
                if (session2 == null) {
                    matchQueue.offer(player1);
                    return;
                }
                // 两个用户为同一个人,理论上也不存在
                if (session1 == session2) {
                    matchQueue.offer(player1);
                    return;
                }

                // 将 这两个玩家放在同一个游戏房间中
                Room room = new Room();
                roomManager.add(room,player1.getUserId(), player2.getUserId());

                // 给玩家反馈 成功匹配到对手了
                MatchResponse response1 = new MatchResponse();
                response1.setOk(true);
                response1.setMessage("matchSuccess");

                MatchResponse response2 = new MatchResponse();
                response2.setOk(true);
                response2.setMessage("matchSuccess");

                session1.sendMessage(new TextMessage(objectMapper.writeValueAsString(response1)));
                session2.sendMessage(new TextMessage(objectMapper.writeValueAsString(response2)));

            } catch (IOException | InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
